#region File Description
//-----------------------------------------------------------------------------
// MessageBoxScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace TankWars
{
    /// <summary>
    /// A popup message box screen, used to display game stats
    /// whenever requested (i.e. end of the game or after a player's tank dies)
    /// </summary>
    class StatsScreen : GameScreen
    {
        #region Fields

        // Stores the text title
        string titleText;        

        // Gradient used for filling stats box
        Texture2D gradientTexture;

        // Use a big font for the title and a plain font for displaying stats
        SpriteFont titleFont;
        SpriteFont statsFont;

        // List of player objects with the current stats of each
        List<Player> playerStats;

        #endregion

        #region Event

        public event EventHandler<EventArgs> Cleared;

        #endregion

        #region Initialization


        /// <summary>
        /// Constructor lets the caller specify whether to include the standard
        /// "Current Game Stats" title.
        /// </summary>
        public StatsScreen(List<Player> players, string title)
        {
            titleText = title;

            playerStats = players;
            
            IsPopup = true;

            TransitionOnTime = TimeSpan.FromSeconds(0.2);
            TransitionOffTime = TimeSpan.FromSeconds(0.2);
        }


        /// <summary>
        /// Loads graphics content for this screen. This uses the shared ContentManager
        /// provided by the Game class, so the content will remain loaded forever.
        /// Whenever a subsequent MessageBoxScreen tries to load this same content,
        /// it will just get back another reference to the already loaded data.
        /// </summary>
        public override void LoadContent()
        {
            ContentManager content = ScreenManager.Game.Content;

            gradientTexture = content.Load<Texture2D>("gradient");

            titleFont = ScreenManager.Font;
            statsFont = content.Load<SpriteFont>("Fonts\\RockwellFont");
        }


        #endregion

        #region Handle Input


        /// <summary>
        /// Responds to user input, clearing the stats box.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input.MenuSelect || input.MenuClick || input.MenuCancel)
            {
                // Raise the cleared event, then exit the message box.
                if (Cleared != null)
                    Cleared(this, EventArgs.Empty);

                ExitScreen();
            }
        }


        #endregion

        #region Draw

        /// <summary>
        /// Draws the message box.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // Assign header text
            string headerName = "NAME";
            string headerKills = "KILLS";
            string headerLives = "LIVES";

            // Create some spacing measurements variables (in pixels)
            float spaceBetweenColumns = 50;
            float tempNameWidthMeasure = 0;
            float leftAlignX = 0;
            Vector2 nameColumnSize = Vector2.Zero;
            Vector2 killsColumnSize = statsFont.MeasureString(headerKills);
            Vector2 livesColumnSize = statsFont.MeasureString(headerLives);

            // Calculate maximum width for name column
            foreach (Player player in playerStats)
            {
                tempNameWidthMeasure = statsFont.MeasureString(player.Name).X;

                // If player's name is longer than current longest, replace
                if (tempNameWidthMeasure > nameColumnSize.X)
                {
                    nameColumnSize.X = tempNameWidthMeasure;
                }
            }

            // Define a new sprite batch
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;            

            // Darken down any other screens that were drawn beneath the popup.
            ScreenManager.FadeBackBufferToBlack(TransitionAlpha * 1 / 2);

            // Center the message text in the viewport.
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
                        
            // Width is the sum of the columns and spaces.
            float textWidth = nameColumnSize.X + killsColumnSize.X + livesColumnSize.X + 2 * spaceBetweenColumns;
            // If title is wider than total stats, use it as width instead
            if (textWidth < titleFont.MeasureString(titleText).X)
            {
                textWidth = titleFont.MeasureString(titleText).X;
            }
            // Height is sum of players multiplied by font height, plus title and header heights
            float textHeight = (playerStats.Count * (nameColumnSize.Y + statsFont.LineSpacing))
                + (titleFont.MeasureString("S").Y + titleFont.LineSpacing) + nameColumnSize.Y;
            // Text size is a vector2 of the dimensions, position is centered in viewport,
            //  and left align is set to beginning text X.
            Vector2 textSize = new Vector2(textWidth, textHeight);
            Vector2 textPosition = (viewportSize - textSize) / 2;
            leftAlignX = textPosition.X;

            // The background includes a border somewhat larger than the text itself.
            const int hPad = 20;
            const int vPad = 20;

            Rectangle backgroundRectangle = new Rectangle((int)textPosition.X - hPad,
                                                          (int)textPosition.Y - vPad,
                                                          (int)textSize.X + hPad * 2,
                                                          (int)textSize.Y + vPad * 2);

            // Fade the popup alpha during transitions.
            Color color = new Color(255, 255, 255, TransitionAlpha);

            spriteBatch.Begin();

            // Draw the background rectangle.
            spriteBatch.Draw(gradientTexture, backgroundRectangle, color);

            // Draw the title text.
            spriteBatch.DrawString(titleFont, titleText, textPosition, color);

            // Add space between title and stats
            textPosition += new Vector2(0, titleFont.LineSpacing + statsFont.LineSpacing);

            // Draw Stats Header
            // Name...
            spriteBatch.DrawString(statsFont, headerName, textPosition, Color.Yellow);
            // space...
            textPosition += new Vector2(nameColumnSize.X + spaceBetweenColumns, 0);
            // Kills...
            spriteBatch.DrawString(statsFont, headerKills, textPosition, Color.Yellow);
            // another space...
            textPosition += new Vector2((float)(killsColumnSize.X + spaceBetweenColumns), 0);
            // Lives...
            spriteBatch.DrawString(statsFont, headerLives, textPosition, Color.Yellow);
            // reset X position and add Y space for player stats
            textPosition.X = leftAlignX;
            textPosition.Y += statsFont.LineSpacing;

            // Draw the stats text for each player.
            foreach (Player player in playerStats)
            {
                // Print player name
                spriteBatch.DrawString(statsFont, player.Name, textPosition, color);
                // Add space
                textPosition += new Vector2(nameColumnSize.X + spaceBetweenColumns, 0);
                // Convert int to string and print player kills
                string playerKills = string.Empty;
                playerKills += player.Kills;
                spriteBatch.DrawString(statsFont, playerKills, textPosition, color);
                // Add space
                textPosition += new Vector2(killsColumnSize.X + spaceBetweenColumns, 0);
                // Convert to string and print player lives
                string playerLives = string.Empty;
                playerLives += player.Lives;
                spriteBatch.DrawString(statsFont, playerLives, textPosition, color);
                // Add space and left-align
                textPosition.X = leftAlignX;
                textPosition.Y += statsFont.LineSpacing;
            }

            // Done with the sprite batch
            spriteBatch.End();
        }


        #endregion
    }
}
